package cn.mayaslight.wechat.service;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;

import cn.mayaslight.common.cache.SysCfgCache;
import cn.mayaslight.common.springbean.CacheManager;
import cn.mayaslight.common.utils.SyncUtils;
import cn.mayaslight.wechat.api.SnsAPI;
import cn.mayaslight.wechat.api.UserAPI;
import cn.mayaslight.wechat.api.bean.SnsToken;
import cn.mayaslight.wechat.api.bean.UserInfo;
import cn.mayaslight.wechat.common.WeChatConsts;
import cn.mayaslight.wechat.springbean.TokenGetter;
import cn.mayaslight.wechat.utils.ExpireSet;

public abstract class PermissionAssignService {
	
	private static ExpireSet<String> expireSet = new ExpireSet<String>();
	
	/** 注入appId */
	protected String appId(){
		return CacheManager.loadUniqueByKey(SysCfgCache.class, WeChatConsts.CacheKeys.APPID_KEY).getCfgVal();
	}
	
	/** 注入appSecret */
	protected String appSecret(){
		return CacheManager.loadUniqueByKey(SysCfgCache.class, WeChatConsts.CacheKeys.APPSECRET_KEY).getCfgVal();
	}
	
	/** 注入iscp */
	protected boolean iscp(){
		String isqyStr = CacheManager.loadUniqueByKey(SysCfgCache.class, WeChatConsts.CacheKeys.ISQY).getCfgVal();
		return Boolean.parseBoolean(isqyStr);
	}
	
	/** 获取缓存/Cookie中的userKey */
	protected abstract String getUser(HttpServletRequest request, HttpServletResponse response);
	
	/** 获取请求中的code */
	protected abstract String getCode();
	
	/** 失败处理方法 */
	protected abstract String error(HttpServletRequest request, HttpServletResponse response);
	
	/** 成功处理方法 */
	protected abstract String success(HttpServletRequest request, HttpServletResponse response, String userKey);
	
	public boolean exec(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		String userKey = getUser(request, response);
		if(StringUtils.isBlank(userKey)){
			String code = getCode();
			if(!StringUtils.isBlank(code)){
				synchronized(SyncUtils.getLock(code)){
					if(!expireSet.contains(code)){
						expireSet.add(code);
						if(iscp()){
							UserInfo userInfo = UserAPI.qyUserInfo(TokenGetter.getInstance().get(), code);
							userKey = userInfo.getUserId();
						}else{
							SnsToken snsToken = SnsAPI.oauth2AccessToken(appId(), appSecret(), code);
							userKey = snsToken.getOpenid();
						}
					}else{
						userKey = getUser(request, response);
						if(StringUtils.isBlank(userKey)){
							error(request, response);
							return false;
						}
					}
				}
			}else{
				error(request, response);
				return false;
			}
		}
		success(request, response, userKey);
		return true;
	}

}
